Add --media-scan to register pushed files with MediaStore#6852
Add --media-scan to register pushed files with MediaStore#6852eret9616 wants to merge 4 commits into
Conversation
When a file is dropped on the scrcpy window, it is pushed to the device with "adb push" but MediaStore is not updated, so gallery apps cannot see the new file. Many gallery apps also filter out /sdcard/Download/, which is the default push target. With --media-scan enabled: - if --push-target is not set, image files (.jpg, .png, .heic, ...) are pushed to /sdcard/Pictures/ and video files (.mp4, .mkv, ...) to /sdcard/Movies/ instead of /sdcard/Download/; - after each successful push, "cmd media_scanner scan-file <path>" is invoked on the device to trigger a MediaStore scan. An explicit --push-target still wins for all file types and is scanned from that location. The cmd media_scanner shell command is available since Android 8.0.
|
On a Pixel 8 with Android 16: $ adb shell cmd media_scanner
cmd: Can't find service: media_scanner |
snprintf is used in build_remote_path() but the header was missing, which fails on toolchains that don't pull it in transitively (e.g. gcc on Linux with -std=c11).
|
Huh, didn't realize stock Android dropped it too — thought it was just OEM ROMs. I'll fix the description and the comment in the code. The PR already falls back to Could you try this on the Pixel 8 and see if the gallery picks it up? If that's also dead, only path I see is going through MediaStore from the server side ( |
public static void scanFile (Context context,
String[] paths,
String[] mimeTypes,
MediaScannerConnection.OnScanCompletedListener callback)The API itself was added in Android 2.2, I only tested it on Andorid 13 and Android 16. Also mentioned by |
The previous implementation used `adb shell cmd media_scanner scan-file` with `am broadcast MEDIA_SCANNER_SCAN_FILE` as fallback. Both are unreliable on modern Android: - `cmd media_scanner` is missing on stock Android 16 (Pixel) and many OEM ROMs; - `MEDIA_SCANNER_SCAN_FILE` broadcast was deprecated in Android 12. Instead, send a new SCAN_FILE control message after a successful push, and let the scrcpy server invoke MediaStore's `scan_file` provider call directly through `ContentResolver.call(MediaStore.AUTHORITY, "scan_file", path, null)`, reusing the existing FakeContext. This is the same path that `MediaStore.scanFile()` and `adb shell content call --uri content://media --method scan_file --arg <path>` go through, and works on every Android version exposing MediaStore. Verified on OnePlus PGZ110 (Android 13): files dragged into the scrcpy window appear in the gallery within seconds, with owner_package_name= com.android.shell as expected.
|
@yume-chan thanks, went with your suggestion. Server now handles a new SCAN_FILE control message and calls Works on my OnePlus 13. @rom1v mind giving it another go on the Pixel when you get a chance? |
|
This works on a Pixel 8: I also found an old commit 190a90f (on branch But if it works now using However, I would prefer not to auto-detect images/videos to change the target directory, just push to "push-target" whatever it is, then scan this directory. Also, if there are no downsides, I think an option |
Per review feedback from rom1v on Genymobile#6852: - drop the --media-scan opt-in flag: MediaStore scan is now always triggered after a successful drag-and-drop push; - drop the image/video extension routing to /sdcard/Pictures/ and /sdcard/Movies/: tests on Pixel 8 / Android 17 and OnePlus PGZ110 / ColorOS 13 confirm Google Photos main view only surfaces DCIM folders regardless of target dir, while scan alone is enough to make files reachable via the system Photo Picker and gallery folder views. The CLI surface goes back to a single --push-target option; the SCAN_FILE control message path introduced previously is preserved.
|
Done in fda146c — both the routing and the --media-scan flag are gone, scan runs unconditionally now. Tested on a Pixel 8 emulator (Android 17) and the OnePlus PGZ110 from the original report, both fine. Doc updated accordingly. |
|
Thank you. 👍 I made some changes, the resulting branch is Firstly, I removed the For example: sometimes creates a file Instead, for simplicity, I always request to scan the "push target" directory (by default I also added unit tests for the control message serialization. One remaining problem on: Bundle out = FakeContext.get().getContentResolver().call(MediaStore.AUTHORITY, "scan_file", path, null);
so it does not work on older versions (tested on Android 6). We should probably use (the equivalent of): (like in 190a90f) as a fallback, or even as the main method (since it still works on Android 16). |
|
On
|
Refs #6851 (also discussed in #6200).
Pushed files (especially images dragged into the window) don't show in the gallery: MediaStore isn't notified and most vendor galleries filter
/sdcard/Download/out. See the linked issue for the full reasoning.This adds an opt-in
--media-scan:/sdcard/Pictures/and/sdcard/Movies/when--push-targetis not setcmd media_scanner scan-fileafter each push (Android 8+), witham broadcast MEDIA_SCANNER_SCAN_FILEas fallback for ROMs that strip the shell service (OnePlus / ColorOS confirmed — first call returnsCan't find service)--push-targetkeeps full controlTested on OnePlus PGZ110 (Android 13), drag-and-drop a
.pngshows up in the gallery within seconds.